01 AJAX 入门
知识点自测
如下对象取值的方式哪个正确?
jslet obj = { name: '黑马', };- A:
obj.a - B:
obj()a
答案
正确的取值方式是
obj.name。在给定的对象中,属性名是name,因此应该使用点符号 (.) 来访问该属性的值。- A:
哪个赋值会让浏览器解析成标签显示?
jslet ul = document.querySelector('#ul'); let str = `<span>我是span标签</span>`;- A:
ul.innerText = str - B:
ul.innerHTML = str
答案
- 选项 A (
ul.innerText = str) 会将字符串str的内容直接作为纯文本插入到ul元素中,而不会解析为 HTML 标签。 - 选项 B (
ul.innerHTML = str) 将字符串str的内容插入到ul元素的内部,这将被浏览器解析为 HTML 标签并显示在页面上。innerHTML属性允许在元素内插入 HTML 标记。 - 答案是 B。
- A:
哪个是获取输入框值的方式?
jslet theInput = document.querySelector('#input');- A:
theInput.innerHTML - B:
theInput.value
答案
- 选项 B (
theInput.value) 用于获取输入框的值。value属性用于表示输入框的当前值,而不同于innerHTML,后者用于获取或设置元素内的 HTML 内容。
- A:
哪个是用于获取标签内容?
jslet theP = document.querySelector('#p');- A:
theP.innerHTML = '内容' - B:
theP.innerHTML
答案
- 选项 B (
theP.innerHTML) 表示获取元素theP的内部 HTML 内容。这将返回标签内的所有内容,包括嵌套的 HTML 标签。 - 选项 A (
theP.innerHTML = '内容') 是用于设置元素的 HTML 内容,而不是获取。 - 答案是 B。
- A:
哪个是数组的映射方法?
- A:
arr.forEach - B:
arr.map
答案
- 选项 B (
arr.map) 是用于在数组的每个元素上调用一个提供的函数,并返回一个新数组,包含每次函数调用的结果。这允许你对数组的每个元素进行转换、修改或其他操作,并生成一个新的数组。
- A:
数组转字符串并指定拼接符的是哪个?
- A:
arr.join() - B:
arr.split()
答案
- 数组转字符串并指定拼接符的方法是
arr.join()。答案是 A。 - 选项 A (
arr.join()) 是用于将数组的所有元素连接成一个字符串。你可以通过在括号内指定拼接符来定义连接的方式,例如arr.join(', ')将数组元素用逗号和空格连接起来。 - 选项 B (
arr.split()) 是用于将字符串分割为数组的方法,并不适用于将数组转换为字符串。
- A:
函数传参的方式哪个是正确的?
jsfunction showAlert(msg, className) {}- A:
showAlert('消息', '类名') - B:
showAlert()
答案
- 选项 A (
showAlert('消息', '类名')) 是正确的,因为函数showAlert定义了两个参数msg和className,在调用函数时,传递相应数量和顺序的参数,即'消息'和'类名'。 - 选项 B (
showAlert()) 是不正确的,因为函数showAlert需要两个参数,而在这个调用中没有提供任何参数。函数调用应该符合函数定义的参数数量和顺序。
- A:
以下哪套代码可以实现对象属性的简写?
jsconst username = '老李'; let obj = { username: username, };jsconst user = '老李'; let obj = { username: user, };答案
- 简写对象属性的方式是使用对象属性值的变量名作为属性名,不需要重复写属性名。在给定的选项中,选项 B 就是采用了对象属性的简写形式。
以下代码的值是多少?
jsconst age = 10; const result = age > 18 ? '成年了' : '未成年';- A:
'成年了' - B:
'未成年'
答案
- 给定的代码使用了条件(三元)运算符,根据条件的真假返回不同的值。在这个例子中,条件是
age > 18,如果条件为真,则结果是'成年了',否则结果是'未成年'。 - 由于给定的
age是 10,不大于 18,所以条件为假,因此结果是'未成年'。 - 所以,正确的答案是 B:
'未成年'。
- A:
以下哪个方法可以添加一个额外类名?
- A:
标签对象.classList.add() - B:
标签对象.classList.contains()
答案
- 选项 A (
标签对象.classList.add()) 表示向元素的类列表中添加一个或多个类名。这是用于添加额外类名的方法。 - 选项 B (
标签对象.classList.contains()) 则用于检查元素的类列表中是否包含特定的类名。 - 答案是 A。
- A:
学习目标
- 掌握 axios 相关参数,从服务器获取并解析展示数据
- 掌握接口文档的查看和使用
- 掌握在浏览器的 network 面板中查看请求和响应的内容
- 了解请求和响应报文的组成部分
AJAX 概念和 axios 使用
学习目标
- 了解 AJAX 概念并掌握 axios 库基本使用
什么是 AJAX
- AJAX(Asynchronous JavaScript and XML)异步 JavaScript 和 XML。
- AJAX 是一种使用 XMLHttpRequest 技术构建更复杂,动态的网页的编程实践。
- AJAX 允许只更新一个 HTML 页面的部分 DOM,而无须重新加载整个页面。AJAX 还允许异步工作,这意味着当网页的一部分正试图重新加载时,你的代码可以继续运行(相比之下,同步会阻止代码继续运行,直到这部分的网页完成重新加载)。
- 通过交互式网站和现代 Web 标准,AJAX 正在逐渐被 JavaScript 框架中的函数和官方的
Fetch API标准取代。

axios 使用
引入 axios.js 文件到自己的网页中
html<!-- 360 --> <script crossorigin="anonymous" integrity="sha512-JWQFV6OCC2o2x8x46YrEeFEQtzoNV++r9im8O8stv91YwHNykzIS2TbvAlFdeH0GVlpnyd79W0ZGmffcRi++Bw==" src="https://lib.baomitu.com/axios/1.6.3/axios.min.js"></script> <!-- cdnjs --> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.3/axios.min.js" integrity="sha512-JWQFV6OCC2o2x8x46YrEeFEQtzoNV++r9im8O8stv91YwHNykzIS2TbvAlFdeH0GVlpnyd79W0ZGmffcRi++Bw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <!-- jsDelivr --> <script src="https://cdn.jsdelivr.net/npm/axios@1.6.3/dist/axios.min.js" integrity="sha256-OgjfiL+Y/3OY7dtKrPY7eizu+Zt+p9dWsAWROQsfCKU=" crossorigin="anonymous"></script> <!-- unpkg --> <script src="https://unpkg.com/axios@1.6.3/dist/axios.min.js"></script>明确 axios 函数的使用语法
jsaxios({ url: '目标资源地址', }).then((result) => { // 对服务器返回的数据做后续处理 });注意
- 请求的 url 地址,就是标记资源的网址
- then 方法这里先体验使用,由来后续会讲到
案例 - 获取省份列表数据
案例 - 获取省份列表数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>01 axios 使用 - 获取省份列表数据</title>
</head>
<body>
<p class="province-list"></p>
<!-- <script src="https://lib.baomitu.com/axios/1.6.3/axios.min.js"></script> -->
<script src="./js/axios.min.js"></script>
<script>
var config = {
method: 'get',
// url: 'https://ajax-api.itheima.net/api/province',
url: 'http://hmajax.itheima.net/api/province',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0'
}
};
axios(config)
.then(response => {
console.log(response.data)
console.log(JSON.stringify(response.data))
// console.log(response.data.data.join(' '))
// document.querySelector('.province-list').innerHTML = response.data.data.join(' ')
console.log(response.data.list.join(' '))
document.querySelector('.province-list').innerHTML = response.data.list.join(' ')
})
</script>
</body>
</html>总结
AJAX 有什么用?
- 浏览器和服务器之间通信,动态数据交互
AJAX 如何学:
- 先掌握 axios 库使用,再了解 XMLHttpRequest 原理
这一节 axios 体验步骤(语法)?
- 引入 axios 库,使用 axios 相关语法
认识 URL
学习目标
- 了解 URL 的组成和作用
为什么要认识 URL
虽然是后端给我的一个地址,但是哪部分标记的是服务器电脑,哪部分标记的是资源呢?所以为了和服务器有效沟通我们要认识一下。
什么是 URL
- 和 Hypertext 以及 HTTP 一样,URL 是 Web 中的一个核心概念。它是浏览器用来检索 web 上公布的任何资源的机制。
- URL 代表着是统一资源定位符(Uniform Resource Locator)。URL 无非就是一个给定的独特资源在 Web 上的地址。理论上说,每个有效的 URL 都指向一个唯一的资源。这个资源可以是一个 HTML 页面,一个 CSS 文档,一幅图像,等等。而在实际中,也有一些例外,最常见的情况就是一个 URL 指向了不存在的或是被移动过的资源。由于通过 URL 呈现的资源和 URL 本身由 Web 服务器处理,因此 web 服务器的拥有者需要认真地维护资源以及与它关联的 URL。
- 文档:什么是 URL? - 学习 Web 开发 | MDN
- 其它
格式
- 标准格式:
[协议类型]://[服务器地址]:[端口号]/[资源层级 UNIX 文件路径][文件名]?[查询]#[片段 ID] - 完整格式:
[协议类型]://[访问资源需要的凭证信息]@[服务器地址]:[端口号]/[资源层级 UNIX 文件路径][文件名]?[查询]#[片段 ID]- 例子:
https://developer.mozilla.org/zh-CN/search?q=URL - 协议类型:
https - 域名:
- 服务器地址:
developer.mozilla.org - 端口号:
80(默认端口号可以省略)
- 服务器地址:
- 资源路径:
- 资源层级 UNIX 文件路径:
/zh-CN - 文件名:
search
- 资源层级 UNIX 文件路径:
- 参数:
- 查询:
q=URL - 片段 ID:
#
- 查询:
- 例子:
Tip
你可能想到一个 URL 类似普通信件的地址:
- 协议代表你要使用的邮政服务
- 域名是城市或者城镇,端口则像邮政编码;
- 路径代表着你的信件所有递送的大楼;
- 参数则提供额外的信息,如大楼所在单元;
- 锚点表示信件的收件人。
协议
http是协议。它表明了浏览器必须使用何种协议。它通常都是 HTTP 协议或是 HTTP 协议的安全版,即 HTTPS。Web 需要它们二者之一,但浏览器也知道如何处理其他协议,比如
mailto:(打开邮件客户端)或者ftp:(处理文件传输),所以当你看到这些协议时,不必惊讶。HTTP 协议类型
HTTP (The HyperText Transfer Protocol,超文本传输协议) 是用于在 Web 上传输超媒体文件的底层 协议 ,最典型场景的是在浏览器和服务器之间传递数据,以供人们浏览。现行的 HTTP 标准的版本是 HTTP/2。
http://称为schema,是 URI 的组成部分,一般位于网络地址的开头。以https://developer.mozilla.org为例,该地址说明请求文档时使用 HTTP 协议;这里的 https 代指 HTTP 协议的安全版本,即 SSL (或称 TLS)HTTP 是基于文本的 (所有的通信都以纯文本的形式进行) 以及无状态的 (当前通信状态不会发现以前的通信状态),该特性极大方便了在 www 上浏览网页的人。除此之外,HTTP 也可以用于构建服务器之间交互的 REST web 服务,以及使得网站内容更加动态化的 AJAX 请求。
- HTTP/2 是 HTTP 网络协议 的一个重要版本。HTTP / 2 的主要目标是通过启用完整的请求和响应多路复用来减少 延迟,通过有效压缩 HTTP 标头字段来最小化协议开销,并增加对请求优先级和服务器推送的支持。
- HTTP/2 不会修改 HTTP 协议的语义。HTTP 1.1 中的所有核心概念(例如 HTTP 方法,状态码,URI 和 headers)都得以保留。而是修改了 HTTP/2 数据在客户端和服务器之间的格式(帧)和传输方式,这两者都管理整个过程,并在新的框架层内隐藏了应用程序的复杂性。所以,所有现有的应用程序都可以不经修改地交付。
- HTTP/3是继 HTTP/2 即将到来的 HTTP 网络协议的 主要修订版。HTTP/3 的要点是它使用名为 QUIC 的新 UDP 协议代替 TCP。
HTTPS 协议类型
域名
www.example.com是域名。它表明正在请求哪个 Web 服务器。或者,可以直接使用 IP address,但是因为它不太方便,所以它不经常在网络上使用。:80是端口。它表示用于访问 Web 服务器上的资源的技术 "门"。如果 Web 服务器使用 HTTP 协议的标准端口(HTTP 为 80,HTTPS 为 443)来授予其资源的访问权限,则通常会被忽略。否则是强制性的。
资源路径
/path/to/myfile.html是网络服务器上资源的路径。在 Web 的早期阶段,像这样的路径表示 Web 服务器上的物理文件位置。- 如今,它主要是由没有任何物理现实的 Web 服务器处理的抽象。
参数
?key1=value1&key2=value2是提供给网络服务器的额外参数。这些参数是用&符号分隔的键/值对列表。- 在返回资源之前,Web 服务器可以使用这些参数来执行额外的操作。
- 每个 Web 服务器都有自己关于参数的规则,唯一可靠的方式来知道特定 Web 服务器是否处理参数是通过询问 Web 服务器所有者。
锚点
#SomewhereInTheDocument是资源本身的另一部分的锚点。- 锚点表示资源中的一种 "书签",给浏览器显示位于该 "加书签" 位置的内容的方向。
- 例如,在 HTML 文档上,浏览器将滚动到定义锚点的位置; 在视频或音频文档上,浏览器将尝试转到锚代表的时间。
- 值得注意的是,
#后面的部分(也称为片段标识符)从来没有发送到请求的服务器。
案例 - 获取新闻列表
案例 - 获取新闻列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>02 认识 URL - 获取新闻列表</title>
</head>
<body>
<div class="news">
<ul class="news-list"></ul>
</div>
<script src="./js/axios.min.js"></script>
<script>
var config = {
method: 'get',
// url: 'https://ajax-api.itheima.net/api/news',
url: 'http://hmajax.itheima.net/api/news',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0'
}
};
axios(config)
.then(response => {
console.log(response.data)
console.log(JSON.stringify(response.data.data))
console.log(response.data.data.map(item => item.title).join('<br>'))
document.querySelector('.news-list').innerHTML = response.data.data.map(item => `<li>${item.title}</li>`).join('')
})
</script>
</body>
</html>总结
URL 是什么?
- 统一资源定位符,网址,用于访问服务器上资源
请解释这个 URL,每个部分作用?
bashhttp://hmajax.itheima.net/api/news 协议://域名/资源路径 - 协议:http - 域名:hmajax.itheima.net - 资源路径:api/news
URL 查询参数
学习目标
- 掌握 - 通过 URL 传递查询参数,获取匹配的数据
什么是查询参数
- 携带给服务器额外信息,让服务器返回我想要的某一部分数据而不是全部数据
- 举例:查询河北省下属的城市列表,需要先把河北省传递给服务器

查询参数的语法
- 在 url 网址后面用?拼接格式:
http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值2 - 参数名一般是后端规定的,值前端看情况传递即可
axios 如何携带查询参数
- 使用
params选项即可
axios({
url: '目标资源地址',
params: {
参数名: 值,
},
}).then((result) => {
// 对服务器返回的数据做后续处理
});案例 - 获取河北省下属的城市列表
案例 - 获取河北省下属的城市列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>03 URL 查询参数 - 获取河北省下属的城市列表</title>
</head>
<body>
<p class="province-city"></p>
<script src="./js/axios.min.js"></script>
<script>
var config = {
method: 'get',
// url: 'https://ajax-api.itheima.net/api/city',
url: 'http://hmajax.itheima.net/api/city',
params: {
pname: '河北省'
},
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0'
}
};
axios(config)
.then(response => {
console.log(response.data)
console.log(JSON.stringify(response.data))
console.log(response.data.list.join(' '))
document.querySelector('.province-city').innerHTML = response.data.list.join(' ')
})
</script>
</body>
</html>总结
URL 查询参数有什么用?
- 浏览器提供给服务器额外信息,获取对应的数据
axios 要如何携带查询参数?
- 使用 params 选项,携带参数名和值在对象结构中
案例 - 查询地区列表
案例 - 查询地区列表
- 需求:根据输入的省份名字和城市名字,查询下属地区列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>04 查询地区列表</title>
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" integrity="sha256-MBffSnbbXwHCuZtgPYiwMQbfE7z+GOZ7fBPCNB06Z98=" crossorigin="anonymous"> -->
<link rel="stylesheet" href="./css/bootstrap.min.css">
</head>
<body class="p-3">
<div class="container">
<h2>04 查询地区列表</h2>
<form class="form-group row" id="editForm">
<div class="mb-3 col">
<label for="province" class="form-label">省份</label>
<select class="form-select" id="province" name="province" onchange="updateCity()">
<option value="北京" selected>北京</option>
<option value="甘肃省">甘肃省</option>
<option value="辽宁省">辽宁省</option>
<option value="河北省">河北省</option>
<option value="西藏自治区">西藏自治区</option>
</select>
</div>
<div class="mb-3 col">
<label for="city" class="form-label">城市</label>
<select class="form-select" id="city" name="city">
<option value="北京市" selected>北京市</option>
</select>
</div>
</form>
<button class="btn btn-primary sel-btn mb-3" type="button">查询</button>
<div class="mt-3 result">
<p>地区列表</p>
<ul class="list-group">
<li class="list-group-item">东城区</li>
</ul>
</div>
</div>
<script src="./js/axios.min.js"></script>
<script>
function updateCity() {
var province = document.getElementById("province").value;
// console.log(province);
var citySelect = document.getElementById("city");
// 清空城市下拉菜单
citySelect.innerHTML = "";
if (province === "北京") {
var cities = ["北京市"];
} else if (province === "甘肃省") {
var cities = ["兰州市", "嘉峪关市", "金昌市", "白银市", "天水市", "武威市", "张掖市", "平凉市", "酒泉市", "庆阳市", "定西市", "陇南市", "临夏回族自治州", "甘南藏族自治州"];
} else if (province === "辽宁省") {
var cities = ["沈阳市", "大连市", "鞍山市", "抚顺市", "本溪市", "丹东市", "锦州市", "营口市", "阜新市", "辽阳市", "盘锦市", "铁岭市", "朝阳市", "葫芦岛市"];
} else if (province === "河北省") {
var cities = ["石家庄市", "唐山市", "秦皇岛市", "邯郸市", "邢台市", "保定市", "张家口市", "承德市", "沧州市", "廊坊市", "衡水市"];
} else if (province === "西藏自治区") {
var cities = ["拉萨市", "昌都地区", "山南地区", "日喀则地区", "那曲地区", "阿里地区", "林芝地区"];
} else {
var cities = [];
}
for (var i = 0; i < cities.length; i++) {
var option = document.createElement("option");
option.text = cities[i];
option.value = cities[i];
citySelect.add(option);
}
}
</script>
<script>
document.querySelector(".sel-btn").onclick = function () {
var province = document.getElementById("province").value;
var city = document.getElementById("city").value;
// console.log(province, city);
var config = {
method: 'get',
// url: `http://hmajax.itheima.net/api/area?pname=${province}&cname=${city}`,
url: `http://hmajax.itheima.net/api/area`,
params: {
pname: province,
cname: city
},
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0'
}
};
axios(config)
.then(response => {
// console.log(response.data)
console.log(JSON.stringify(response.data))
// console.log(response.data.data.join(' '))
// document.querySelector('.province-list').innerHTML = response.data.data.join(' ')
console.log(response.data.list.join(' '))
document.querySelector('.list-group').innerHTML = response.data.list.map(item => `<li class="list-group-item">${item}</li>`).join('')
})
}
</script>
</body>
</html>常用请求方法和数据提交
学习目标
- 掌握如何向服务器提交数据,而不单单是获取数据
- 掌握接收 axios 响应错误信息的处理语法
常用请求方法
| 请求方法 | 操作 |
|---|---|
| GET | 获取数据 |
| POST | 提交数据 |
| PUT | 修改数据(全部) |
| DELETE | 删除数据 |
| PATCH | 修改数据(部分) |
- 请求方法是一些固定单词的英文,例如:
GET,POST,PUT,DELETE,PATCH(这些都是 HTTP 协议规定的),每个单词对应一种对服务器资源要执行的操作。

数据提交
- 前面我们获取数据其实用的就是
GET请求方法,但是 axios 内部设置了默认请求方法就是GET,我们就没有写 - 但是提交数据需要使用
POST请求方法
axios 提交数据到服务器
axios({
url: '目标资源地址',
method: '请求方法',
data: {
参数名: 值,
},
}).then((result) => {
// 对服务器返回的数据做后续处理
});错误处理
在 axios 语法中要如何处理呢?
- 因为,普通用户不会去控制台里看错误信息,我们要编写代码拿到错误并展示给用户在页面上
使用 axios 的 catch 方法,捕获这次请求响应的错误并做后续处理,语法如下:
jsaxios({ // ...请求选项 }) .then((response) => { // 处理成功数据 }) .catch((error) => { // 处理失败错误 });
案例 - 注册账号
案例 - 注册账号
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>05 数据提交 - 注册账号</title>
<link rel="stylesheet" href="./css/bootstrap.min.css">
</head>
<body class="p-3 mb-2 d-flex justify-content-center align-items-center vh-100">
<div class="container p-5 shadow" style="width: 500px; background-color: #f5f5f5; border-radius: 10px;">
<h2>05 注册账号</h2>
<form class="form-group mt-5">
<div class="mb-3">
<label for="exampleInputUsername" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" placeholder="鸡你太美cxk"
aria-describedby="usernameHelp">
<div id="usernameHelp" class="form-text">中英文和数字组成,最少 8 位。</div>
</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" placeholder="987654321"
aria-describedby="passwordHelp">
<div id="passwordHelp" class="form-text">最少 6 位。</div>
</div>
</form>
<button type="submit" class="btn btn-primary mb-3">注册账号</button>
</div>
<script src="./js/axios.min.js"></script>
<script>
var submitBtn = document.querySelector("button[type=submit]");
submitBtn.addEventListener("click", () => {
var username = document.querySelector("#username").value;
var password = document.querySelector("#password").value;
console.log(username, password);
axios.post("http://hmajax.itheima.net/api/register", {
username,
password
}).then(response => {
console.log(response);
console.log(response.data.message);
alert(response.data.message);
}).catch(error => {
console.log(error);
console.log(error.response.data.message);
alert(error.response.data.message);
});
});
</script>
</body>
</html>总结
请求方法最常用的是哪 2 个,分别有什么作用?
POST提交数据GET查询数据
axios 的核心配置项?
url:目标资源地址method:请求方法params:查询参数data:提交的数据
axios 如何拿到请求响应失败的信息?
- 通过 axios 函数调用后,在后面接着调用
.catch方法捕获
- 通过 axios 函数调用后,在后面接着调用
HTTP 协议 - 请求报文
学习目标
- 了解 HTTP 协议中,请求报文的组成和作用
- 了解学习了查看请求报文之后的作用,可以用来辅助错误排查
- HTTP 协议规定了浏览器和服务器返回内容的格式
请求报文
请求报文:是浏览器按照协议规定发送给服务器的内容,例如刚刚注册用户时,发起的请求报文:
propertiesPOST /api/register HTTP/1.1 Accept: application/json, text/plain, */* Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Content-Length: 48 Content-Type: application/json DNT: 1 Host: hmajax.itheima.net Origin: http://127.0.0.1:3000 Proxy-Connection: keep-alive Referer: http://127.0.0.1:3000/ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 {"username":"itheima985","password":"987654321"}这里的格式包含:
- 请求行:请求方法,URL,协议
- 请求头:以键值对的格式携带的附加信息,比如:Content-Type(指定了本次传递的内容类型)
- 空行:分割请求头,空行之后的是发送给服务器的资源
- 请求体:发送的资源
Chrome 的网络面板如何查看请求体

辅助错误排查
- 学习了查看请求报文有什么用呢?
- 可以用来确认我们代码发送的请求数据是否真的正确
- 配套模板代码里,对应 08 标题文件夹里是我同桌的代码,它把登录也写完了,但是无法登录,我们来到模板代码中,找到运行后,在不逐行查看代码的情况下,查看请求报文,看看它登录提交的相关信息对不对,帮他找找问题出现的原因
- 发现请求体数据有问题,往代码中定位,找到类名写错误了
- 代码:在配套文件夹素材里,找到需要对应代码,直接运行,根据报错信息,找到错误原因
总结
- 浏览器发送给服务器的内容叫做
- 请求报文
- 请求报文的组成是什么?
- 请求行,请求头,空行,请求体
- 学会了查看请求报文,对实际开发有什么帮助呢?
- 可以快速确认我们发送的内容是否正确
HTTP 协议 - 响应报文
学习目标
- 了解响应报文的组成
响应报文
响应报文:是服务器按照协议固定的格式,返回给浏览器的内容
propertiesHTTP/1.1 400 Bad Request Content-Length: 54 Accept-Ranges: bytes Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: http://127.0.0.1:3000 Connection: keep-alive Content-Type: application/json; charset=utf-8 Date: Tue, 02 Jan 2024 10:40:27 GMT Keep-Alive: timeout=4 Proxy-Connection: keep-alive Server: nginx Set-Cookie: acw_tc=2f624a4917041920275134830e32870255ed085870f4c45e154d2a290a6754;path=/;HttpOnly;Max-Age=1800 Vary: Origin X-Content-Type-Options: nosniff X-Download-Options: noopen X-Frame-Options: SAMEORIGIN X-Readtime: 10 X-Xss-Protection: 1; mode=block {"code":10005,"message":"账号被占用","data":null}响应报文的组成:
- 响应行(状态行):协议,HTTP 响应状态码,状态信息
- 响应头:以键值对的格式携带的附加信息,比如:Content-Type(告诉浏览器,本次返回的内容类型)
- 空行:分割响应头,控制之后的是服务器返回的资源
- 响应体:返回的资源
HTTP 响应状态码
- 用来表明请求是否成功完成
- 例如:404(客户端要找的资源,在服务器上不存在)
| 状态码 | 含义 |
|---|---|
| 1XX | 信息提示类 |
| 2XX | 成功类 |
| 3XX | 重定向类 |
| 4XX | 客户端错误类 |
| 5XX | 服务器端错误类 |
总结
响应报文的组成?
- 响应行,响应头,空行,响应体
HTTP 响应状态码是做什么的?
- 表明请求是否成功完成,2xx 都是成功的
案例 - 用户登录
案例 - 用户登录
- Alert 提示框添加/去除
.show类名即可实现弹框的出现/隐藏。 - 遇到相同逻辑,重复代码要复用的时候需要封装函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>06 用户登录</title>
<link rel="stylesheet" href="./css/bootstrap.min.css">
<style>
.alert {
transition: .5s;
opacity: 0;
}
.alert.show {
opacity: 1;
}
</style>
</head>
<body class="p-3 mb-2 d-flex justify-content-center align-items-center vh-100">
<div class="container p-5 shadow-lg bg-body-tertiary rounded-4" style="width: 500px;">
<h2>06 用户登录</h2>
<div class="alert alert-success" role="alert">
提示消息
</div>
<form class="form-group" id="editForm">
<div class="mb-3">
<label for="username" class="form-label">用户名</label>
<input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名">
</div>
<div class="mb-3">
<label for="password" class="form-label">密码</label>
<input type="password" class="form-control" id="password" name="password" placeholder="请输入密码">
</div>
</form>
<button type="botton" class="btn btn-primary btn-login">登录</button>
</div>
<script src="./js/axios.min.js"></script>
<script>
function showAlert(message, isSuccess) {
var alert = document.querySelector(".alert");
alert.classList.add("show");
alert.innerHTML = message;
alertStyle = isSuccess ? "alert-success" : "alert-danger";
alert.classList.add(alertStyle);
setTimeout(() => {
alert.classList.remove("show");
alert.classList.remove(alertStyle);
}, 2000);
}
var loginBtn = document.querySelector(".btn-login");
loginBtn.addEventListener("click", () => {
var username = document.querySelector("#username").value;
var password = document.querySelector("#password").value;
console.log(username, password);
if (username.length < 8) {
console.log("用户名最少 8 位");
showAlert("用户名最少 8 位", false);
return;
}
if (password.length < 6) {
console.log("密码最少 6 位");
showAlert("密码最少 6 位", false);
return;
}
axios.post("http://hmajax.itheima.net/api/login", {
username,
password
}).then(response => {
console.log(response);
console.log(response.data.message);
showAlert(response.data.message, true);
}).catch(error => {
console.log(error);
console.log(error.response.data.message);
showAlert(error.response.data.message, false);
});
});
</script>
</body>
</html>form-serialize 插件
使用 form-serialize 插件,快速收集目标表单范围内表单元素的值
语法:
jsconst form = document.querySelector('form'); const data = serialize(form, { hash: true, // true - 收集出来的是一个 JS 对象结构,false - 收集出来的是一个查询字符串格式 empty: true, // true - 收集空值,false - 不收集空值 }); console.log(data); const { username, password } = data;
总结
我们什么时候使用 form-serialize 插件?
- 快速收集表单元素的值
如何使用 form-serialize 插件?
- 先引入插件到自己的网页中,
- 准备 form 和表单元素的 name 属性,
- 使用 serialize 函数,传入 form 表单和配置对象
配置对象中 hash 和 empty 有什么用?
hash决定是收集为 JS 对象还是查询参数字符串,empty决定是否收集空值
案例 - 用户登录 form-serialize
案例 - 用户登录 form-serialize
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>07 用户登录 form-serialize</title>
<link rel="stylesheet" href="./css/bootstrap.min.css">
<style>
.alert {
transition: .5s;
opacity: 0;
}
.alert.show {
opacity: 1;
}
</style>
</head>
<body class="p-3 mb-2 d-flex justify-content-center align-items-center vh-100">
<div class="container p-5 shadow-lg bg-body-tertiary rounded-4" style="width: 500px;">
<h2>07 用户登录 form-serialize</h2>
<div class="alert alert-success" role="alert">
提示消息
</div>
<form class="form-group" id="editForm">
<div class="mb-3">
<label for="username" class="form-label">用户名</label>
<input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名">
</div>
<div class="mb-3">
<label for="password" class="form-label">密码</label>
<input type="password" class="form-control" id="password" name="password" placeholder="请输入密码">
</div>
</form>
<button type="botton" class="btn btn-primary btn-login">登录</button>
</div>
<script src="./js/axios.min.js"></script>
<script src="./js/form-serialize.js"></script>
<script>
function showAlert(message, isSuccess) {
var alert = document.querySelector(".alert");
alert.classList.add("show");
alert.innerHTML = message;
alertStyle = isSuccess ? "alert-success" : "alert-danger";
alert.classList.add(alertStyle);
setTimeout(() => {
alert.classList.remove("show");
alert.classList.remove(alertStyle);
}, 2000);
}
var loginBtn = document.querySelector(".btn-login");
loginBtn.addEventListener("click", () => {
// var username = document.querySelector("#username").value;
// var password = document.querySelector("#password").value;
// console.log(username, password);
const editForm = document.querySelector("#editForm");
const formData = serialize(editForm, { hash: true, empty: true });
console.log(formData);
const { username, password } = formData;
console.log(username, password);
if (username.length < 8) {
console.log("用户名最少 8 位");
showAlert("用户名最少 8 位", false);
return;
}
if (password.length < 6) {
console.log("密码最少 6 位");
showAlert("密码最少 6 位", false);
return;
}
axios.post("http://hmajax.itheima.net/api/login", {
username,
password
}).then(response => {
console.log(response);
console.log(response.data.message);
showAlert(response.data.message, true);
}).catch(error => {
console.log(error);
console.log(error.response.data.message);
showAlert(error.response.data.message, false);
});
});
</script>
</body>
</html>今日重点
axios 的配置项有哪几个,作用分别是什么?
url: 请求的地址。method: 请求的方法,例如GET、POST等。params: 请求的查询参数。data: 请求的请求体数据。headers: 请求的头部信息。
接口文档都包含哪些信息?
- 接口地址 (URL): 请求的地址。
- 请求方法 (Method): 比如
GET、POST、PUT等。 - 请求参数 (Parameters): 包括查询参数、路径参数等。
- 请求体 (Request Body):
POST或者其他有请求体的请求的数据。 - 请求头 (Request Headers): 请求时需要设置的头部信息。
- 响应状态码 (Response Status Code): 服务器返回的状态码,如
200、404等。 - 响应体 (Response Body): 服务器返回的数据。
- 响应头 (Response Headers): 服务器返回的头部信息。
在浏览器中如何查看查询参数/请求体,以及响应体数据?
- 查看查询参数:
- 打开开发者工具 (F12 或右键点击页面选择 "检查")。
- 切换到
Network标签。 - 发起请求后,在列表中选择相应的请求。
- 在右侧的
Headers或Query String Parameters标签下查看查询参数。
- 查看请求体:
- 在
Network标签下选择相应的请求。 - 切换到
Headers标签。 - 在
Request Payload或Form Data中查看请求体数据。
- 在
- 查看响应体:
- 在
Network标签下选择相应的请求。 - 切换到
Response标签。 - 在
Preview或Response部分查看响应体数据。
- 在
- 查看查询参数:
请求报文和响应报文由几个部分组成,每个部分的作用?
- 起始行 (Start Line): 包含请求方法、请求目标 (URI) 和协议版本。
- 头部字段 (Headers): 包含多个键值对,描述请求或响应的属性。
- 空行 (Blank Line): 用于分隔头部字段和消息体的空行。
- 消息体 (Message Body): 包含请求或响应的数据,可以是文本、JSON、XML 等格式的数据。
今日作业
客观题
在线答题:Day01_AJAX 入门
什么是 AJAX(B)?
- A. 浏览器与浏览器通信数据的方式
- B. 浏览器与服务器通信的技术
- C. 本机电脑和其他电脑交互数据的方式
- D. 就是 axios 库
AJAX 和 axios 关系(D)?
- A. AJAX 就是 axios
- B. axios 和 AJAX 没关系
- C. AJAX 是对 axios 进行了封装
- D. AJAX 是浏览器通过 XMLHttpRequest 对象与服务器通信,axios 是第三方库对原生 XMLHttpRequest 相关代码进行封装,使用更简单
以下哪个不是 url 组成部分(C)?
- A. 协议
- B. 域名
- C. 地址
- D. 资源路径
axios 传参要求用查询参数,选择哪个配置项(B)?
- A. url
- B. params
- C. data
- D. method
axios 传参要求用请求体,选择哪个配置项(A)?
- A. data
- B. params
- C. url
- D. method
以下哪个不是 AJAX 请求的方式(D)?
- A. GET
- B. POST
- C. DELETE
- D. PUATC
axios 接收错误结果的方法叫(B)?
- A. then
- B. catch
- C. url
- D. data
以下哪个是浏览器发给服务器的(A)?
- A. 请求报文
- B. 响应报文
- C. 响应状态码
- D. 响应体
服务器返回数据的动作叫(A)?
- A. 响应
- B. 请求
- C. axios
- D. 请求报文
以下哪个是 HTTP 响应状态码(B)?
- A. 49000
- B. 200
- C. 10000
- D. 699
主观题
作业 1 - 微信聊天
目标:完成如下聊天效果
要求:
- 点击发送和敲击回车键,都能发送聊天消息
- 把自己和对方消息都展示到页面上
- 当聊天消息出现滚动条时,始终让最后一条消息出现在视口范围内
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>08 微信聊天</title>
<link rel="stylesheet" href="./css/font_3736758_vxpb728fcyh.css">
<link rel="stylesheet" href="./css/reset.min.css">
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div class="container">
<!-- 头部 -->
<div class="top">
<span>9:41</span>
<div class="icon">
<i class="iconfont icon-xinhao"></i>
<i class="iconfont icon-xinhao1"></i>
<i class="iconfont icon-electricity-full"></i>
</div>
</div>
<!-- 好友名字 -->
<div class="friend_name">
<img src="./assets/arrow-left.png" alt="">
<span>使劲夸夸</span>
</div>
<!-- 聊天区域 -->
<div class="chat">
<ul class="chat_list">
<!-- 他的消息 -->
<li class="left">
<img src="./assets/you.png" alt="">
<span>小宝贝</span>
</li>
<!-- 我的消息 -->
<li class="right">
<span>干啥</span>
<img src="./assets/me.png" alt="">
</li>
</ul>
</div>
<!-- 底部固定 -->
<div class="bottom_div">
<!-- 发送消息 -->
<div class="send_box">
<div class="input_bg">
<input class="chat_input" type="text" placeholder="说点什么吧">
</div>
<img class="send_img" src="./assets/send.png" alt="">
</div>
<!-- 底部黑条 -->
<div class="black_border">
<span></span>
</div>
</div>
</div>
<script src="./js/axios.min.js"></script>
<script src="./js/index.js"></script>
</body>
</html>// 获取机器人回答消息 - 接口地址:http://hmajax.itheima.net/api/robot
// 查询参数名:spoken
// 查询参数值:我说的消息
// 聊天函数:发送消息,获取机器人回答的消息
let chat = () => {
// 获取输入框里的消息
let chatInput = document.querySelector('.chat_input');
// 获取输入框里的内容,去除首尾空格
let chatInputValue = chatInput.value.trim();
console.log(chatInputValue);
// 判断输入框里的内容是否为空
if (chatInputValue.length === 0) {
console.log('输入框里的内容为空!!!');
return;
}
// 获取聊天列表
let chatList = document.querySelector('.chat_list');
// 将输入框里的内容添加到聊天列表,然后清空输入框
chatList.innerHTML += `<li class="right">
<span>${chatInputValue}</span>
<img src="./assets/me.png" alt="">
</li>`;
chatInput.value = '';
// 获取聊天区域
let chatDiv = document.querySelector('.chat');
// 将聊天区域滚动到底部
chatDiv.scrollTop = chatDiv.scrollHeight;
// 发送请求,获取机器人回答的消息
axios.get('http://hmajax.itheima.net/api/robot', {
params: {
spoken: chatInputValue
}
}).then(response => {
// 将机器人回答的消息添加到聊天列表
// console.log(response);
console.log(response.data.data.info.text);
chatList.innerHTML += `<li class="left">
<img src="./assets/you.png" alt="">
<span>${response.data.data.info.text}</span>
</li>`;
// 将聊天区域滚动到底部
chatDiv.scrollTop = chatDiv.scrollHeight;
}).catch(error => {
console.log(error.message);
});
}
// 点击发送
document.querySelector('.send_img').addEventListener('click', chat);
// 敲击回车键
document.querySelector('.chat_input').addEventListener('keyup', e => {
// 判断是否按下回车键
if (e.keyCode === 13) {
chat();
}
})作业 2 - 必要商城搜索
目标:完成如下搜索效果
要求:
- 输入要搜索的关键字,点击放大镜搜索匹配商品
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <title>09 必要商城搜索</title> -->
<title>必要商城_大牌品质 工厂价格</title>
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="./css/common.css" />
<link rel="stylesheet" href="./css/elementUI.css" />
<link rel="stylesheet" href="./css/global.css" />
<link rel="stylesheet" href="./css/iprHeader.css" />
<link rel="stylesheet" href="./css/new.category.css" />
<link rel="stylesheet" href="./css/new.main.css" />
</head>
<body id="pagebody">
<div class="header header-index"></div>
<!-- 导航栏 -->
<div class="nav nav-index">
<div class="clearfix">
<a href="http://www.biyao.com/home/index.html" class="nav-logo"><img src="./assets/logo.png" height="51" /></a>
<div class="nav-category">
<p><span>全部分类</span><i></i></p>
<div>
<ul class="nav-list">
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=621"> 咖啡 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=627"> 饮食 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=691"> 正餐 </a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=279"> 男装 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=294"> 女装 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=35"> 鞋靴 </a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=122"> 眼镜 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=339"> 内衣配饰 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=39"> 运动 </a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=119"> 美妆 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=724"> 个护 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=391"> 母婴 </a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=652"> 生鲜直供 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=51"> 餐厨 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=334"> 电器 </a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=153"> 箱包 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=223"> 数码办公 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=429"> 汽配 </a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=355"> 家纺 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=10"> 家具 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=369"> 家装 </a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=546"> 健康保健 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=685"> 宠物 </a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=816"> 礼品 </a>
</p>
</li>
</ul>
</div>
</div>
<div class="nav-search">
<p><input type="text" id="searchInp" placeholder="请输入要搜索的商品" /><span id="searchButton"></span></p>
<ul style="">
<li>行李箱</li>
<li>洗面奶</li>
<li>枕头</li>
<li>袜子男夏季</li>
<li>防晒霜</li>
<li>洗发水</li>
<li>伞</li>
<li>香水</li>
<li>眼霜</li>
<li>精华</li>
</ul>
</div>
<div class="nav-tab">
<ul>
<li><a href="http://www.biyao.com/home/index.html">首页</a></li>
<li><a href="http://www.biyao.com/classify/newProduct.html">每日上新</a></li>
<li class="border-l"></li>
<li class="nav-tab-last">
<div class="hover_text">
了解必要
<div class="hover_code gzh">
<span>关注必要微信公众号<br />了解你想了解的一切<br />小必姐在此发福利哦</span>
</div>
</div>
</li>
<li class="nav-tab-last" id="appDownload">下载必要 APP</li>
<li class="border-l"></li>
<li class="nav-tab-last">
<div class="hover_text">
我的必要
<div class="hover_code app">
<span>
扫码下载必要 app
<br />
手机用户独享海量权益
</span>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<!-- 右边栏 -->
<ul class="rightBar" style="display: block">
<li class="toggle"></li>
<li class="rightBar-xcx-code toggle novice">
<div class="coupon_red">
<div class="tis">
迎新福利<br />
微信扫码即得
</div>
<div class="rightBar-title">15 元</div>
<div class="count-down" data-time="7200000" id="count-down"></div>
</div>
<div class="rightBar-ercode"></div>
</li>
<li class="rightBar-top" style="display: none"></li>
</ul>
<!-- 分享弹框 -->
<div class="shareCon">
<div>
<p>分享<b></b></p>
<div class="share-main">
<dl>
<dt><img class="share-code" src="./assets/ewm.jpg" /></dt>
<dd>扫一扫,分享给好友!</dd>
</dl>
</div>
</div>
</div>
<!-- 搜索商品列表 -->
<ul class="category-container">
<li>
<ul class="supplier-recommen category-list clearfix">
<!-- 每件搜索商品 -->
<!-- <li>
<a><i><img
src="./js/CghkFmIuDbOAUFjRAADsxoYlvAQ019_360x360.jpg"></i>
<div class="supplier">祖玛珑同原料制造商</div>
<div class="title">【会呼吸的洗发水】风铃草</div>
<div class="priceBox">
<div class="price" price="88"><span
style="color: #F7A701; font-size: 12px; padding-left: 2px;">¥<span
style="font-size:18px;">88</span></span></div>
<div class="mack"><span
style="color:#FB4C81;background:#FFFFFF; border-color:#FB4C81">一起拼</span><span
style="color:#FFFFFF;background:#AB7FD1; border-color:#AB7FD1">精选</span></div>
</div>
<div class="evaluate">653 条好评</div>
</a>
</li> -->
</ul>
</li>
</ul>
<script type="text/javascript" src="./js/jquery-1.8.3.js"></script>
<script type="text/javascript" src="./js/jquery.cookie.js"></script>
<script type="text/javascript" src="./js/md5.js"></script>
<script type="text/javascript" src="./js/masterCommon.js"></script>
<script type="text/javascript" src="./js/jquery.extention.js"></script>
<script type="text/javascript" src="./js/common.js"></script>
<script type="text/javascript" src="./js/qs.min.js"></script>
<script type="text/javascript" src="./js/vue.min.js"></script>
<script type="text/javascript" src="./js/elementUI.min.js"></script>
<script type="text/javascript" src="./js/utils.js"></script>
<script src="./js/smcp.min.js"></script>
<script src="./js/dialog.js"></script>
<script src="./js/axios.min.js"></script>
<script src="./js/index.js"></script>
</body>
</html>// 获取搜索框
let searchInp = document.querySelector('#searchInp');
// 搜索函数:根据搜索框的内容,发送请求,获取数据,渲染到页面上
let search = () => {
// 获取搜索框的内容
let searchContent = searchInp.value;
console.log(searchContent);
// 发送请求
axios
.get('https://hmajax.itheima.net/api-s/searchGoodsList', {
params: {
searchText: searchContent,
page: 1,
everyNum: 16,
},
})
.then((response) => {
// console.log(response);
console.log(response.data.list.data);
// <ul class="supplier-recommen category-list clearfix">
// <!-- 每件搜索商品 -->
// <!-- <li>
// <a><i><img
// src="./lib/CghkFmIuDbOAUFjRAADsxoYlvAQ019_360x360.jpg"></i>
// <div class="supplier">祖玛珑同原料制造商</div>
// <div class="title">【会呼吸的洗发水】风铃草</div>
// <div class="priceBox">
// <div class="price" price="88"><span
// style="color: #F7A701; font-size: 12px; padding-left: 2px;">¥<span
// style="font-size:18px;">88</span></span></div>
// <div class="mack"><span
// style="color:#FB4C81;background:#FFFFFF; border-color:#FB4C81">一起拼</span><span
// style="color:#FFFFFF;background:#AB7FD1; border-color:#AB7FD1">精选</span></div>
// </div>
// <div class="evaluate">653 条好评</div>
// </a>
// </li> -->
// </ul>
// 获取搜索商品列表
let searchGoodsList = document.querySelector('.supplier-recommen');
// console.log(searchGoodsList);
// 判断搜索商品结果是否为空
if (response.data.list.data.length === 0) {
console.log('搜索商品结果为空!!!');
} else {
// 将数据渲染到页面上
searchGoodsList.innerHTML = response.data.list.data.map((item) => `<li>
<a><i><img
src="${item.imageUrl}"></i>
<div class="supplier">祖玛珑同原料制造商</div>
<div class="title">${item.goodsName}</div>
<div class="priceBox">
<div class="price" price="${item.goodsPrice}"><span
style="color: #F7A701; font-size: 12px; padding-left: 2px;">¥<span
style="font-size:18px;">${item.goodsPrice}</span></span></div>
<div class="mack"><span
style="color:#FB4C81;background:#FFFFFF; border-color:#FB4C81">一起拼</span><span
style="color:#FFFFFF;background:#AB7FD1; border-color:#AB7FD1">精选</span></div>
</div>
<div class="evaluate">${item.evalNum} 条好评</div>
</a>
</li>`).join('');
}
}).catch((error) => {
console.log(error.message);
});
};
// 搜索按钮添加点击事件
document.querySelector('#searchButton').addEventListener('click', search);
// 搜索框添加敲击回车键事件
searchInp.addEventListener('keyup', (e) => {
// 判断是否按下回车键
if (e.keyCode === 13) {
search();
}
});排错题
排错题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>案例_登录</title>
<!-- 引入 bootstrap.css -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css">
<!-- 公共 -->
<style>
html,
body {
background-color: #EDF0F5;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.container {
width: 520px;
height: 540px;
background-color: #fff;
padding: 60px;
box-sizing: border-box;
}
.container h3 {
font-weight: 900;
}
</style>
<!-- 表单容器和内容 -->
<style>
.form_wrap {
color: #8B929D !important;
}
.form-text {
color: #8B929D !important;
}
</style>
<!-- 提示框样式 -->
<style>
.alert {
transition: .5s;
opacity: 0;
}
.alert.show {
opacity: 1;
}
</style>
</head>
<body>
<div class="container">
<h3>欢迎 - 登录</h3>
<!-- 登录结果 - 提示框 -->
<div class="alert alert-success" role="alert">
提示消息
</div>
<!-- 表单 -->
<div class="form_wrap">
<form>
<div class="mb-3">
<label for="username" class="form-label">账号名</label>
<input type="text" class="form-control username">
</div>
<div class="mb-3">
<label for="password" class="form-label">密码</label>
<input type="password" class="form-control password">
</div>
<button type="button" class="btn btn-primary btn-login"> 登 录 </button>
</form>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 目标:建议使用 network+console 调试来找到问题(共有 6 处错误)
// 有的问题不会报错,需要自己寻找关键代码来梳理
// 最后完成登录功能
// 获取提示框
const myAlert = document.querySelector('alert')
function alertFn(msg, isSuccess) {
myAlert.classList.add('show')
myAlert.innerText = msg
const bgStyle = isSuccess ? 'alert-success' : 'alert-danger'
myAlert.classList.add(bgStyle)
setTimeout(() => {
myAlert.classList.remove('show')
myAlert.classList.remove(bgStyle)
}, 2000)
}
document.querySelector('.btn-login').addEventListener('click', () => {
const username = document.querySelector('.password').value
const password = document.querySelector('.password').value
if (username.length < 8) {
alertFn('用户名必须大于等于8位', false)
console.log('用户名必须大于等于8位')
return
}
if (password.length < 6) {
alertFn('密码必须大于等于6位', false)
console.log('密码必须大于等于6位')
return
}
axios({
url: 'http://hmajax.itheima.net/api/lgoin',
methods: 'POST',
params: {
user: username,
password
}
}).then(result => {
alertFn(result.data.message, true)
console.log(result)
console.log(result.data.message)
}).catch(error => {
alertFn(error.response.data.message, false)
console.log(error)
console.log(error.response.data.message)
})
})
</script>
</body>
</html>在使用账号密码登录时,控制台报错。
bash10.排错题.html:89 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'classList') at alertFn (10.排错题.html:89:15) at 10.排错题.html:128:9定位代码片段为
js// 获取提示框 const myAlert = document.querySelector('alert') function alertFn(msg, isSuccess) { myAlert.classList.add('show') ... }发现
const myAlert = document.querySelector('alert')出错, 理应为const myAlert = document.querySelector('.alert')登录提示
GET http://hmajax.itheima.net/api/lgoin?user=987654321&password=987654321 404 (Not Found)发现请求体数据有问题以及 url 资源路径有问题 定位代码片段为jsconst username = document.querySelector('.password').value; const password = document.querySelector('.password').value; ... axios({ url: 'http://hmajax.itheima.net/api/lgoin', methods: 'POST', params: { user: username, password }发现 username 和 password 都是获取的
.password的值,应该为jsconst username = document.querySelector('.username').value; const password = document.querySelector('.password').value;发现 url 链接中资源路径为
api/lgoin,理应为api/login发现
methods写错了,应该为method发现应该为
data传递请求体数据,而不是params传递查询参数发现请求体参数名应该为
username和password,而不是user和passwordjsaxios({ url: 'http://hmajax.itheima.net/api/login', method: 'POST', data: { username, password }
排错题 (纠正)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>案例_登录</title>
<!-- 引入 bootstrap.css -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css">
<!-- 公共 -->
<style>
html,
body {
background-color: #EDF0F5;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.container {
width: 520px;
height: 540px;
background-color: #fff;
padding: 60px;
box-sizing: border-box;
}
.container h3 {
font-weight: 900;
}
</style>
<!-- 表单容器和内容 -->
<style>
.form_wrap {
color: #8B929D !important;
}
.form-text {
color: #8B929D !important;
}
</style>
<!-- 提示框样式 -->
<style>
.alert {
transition: .5s;
opacity: 0;
}
.alert.show {
opacity: 1;
}
</style>
</head>
<body>
<div class="container">
<h3>欢迎 - 登录</h3>
<!-- 登录结果 - 提示框 -->
<div class="alert alert-success" role="alert">
提示消息
</div>
<!-- 表单 -->
<div class="form_wrap">
<form>
<div class="mb-3">
<label for="username" class="form-label">账号名</label>
<input type="text" class="form-control username">
</div>
<div class="mb-3">
<label for="password" class="form-label">密码</label>
<input type="password" class="form-control password">
</div>
<button type="button" class="btn btn-primary btn-login"> 登 录 </button>
</form>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 目标:建议使用 network+console 调试来找到问题(共有 6 处错误)
// 有的问题不会报错,需要自己寻找关键代码来梳理
// 最后完成登录功能
// 获取提示框
const myAlert = document.querySelector('.alert')
function alertFn(msg, isSuccess) {
myAlert.classList.add('show')
myAlert.innerText = msg
const bgStyle = isSuccess ? 'alert-success' : 'alert-danger'
myAlert.classList.add(bgStyle)
setTimeout(() => {
myAlert.classList.remove('show')
myAlert.classList.remove(bgStyle)
}, 2000)
}
document.querySelector('.btn-login').addEventListener('click', () => {
const username = document.querySelector('.username').value
const password = document.querySelector('.password').value
if (username.length < 8) {
alertFn('用户名必须大于等于8位', false)
console.log('用户名必须大于等于8位')
return
}
if (password.length < 6) {
alertFn('密码必须大于等于6位', false)
console.log('密码必须大于等于6位')
return
}
axios({
url: 'http://hmajax.itheima.net/api/login',
method: 'POST',
data: {
username,
password
}
}).then(result => {
alertFn(result.data.message, true)
console.log(result)
console.log(result.data.message)
}).catch(error => {
alertFn(error.response.data.message, false)
console.log(error)
console.log(error.response.data.message)
})
})
</script>
</body>
</html>面试题
GET 和 POST 请求方法的区别?
GET 和 POST 请求方式无区别,本质都是一次 HTTP 请求 (TCP 链接), 而 HTTP 请求报文中都包含请求行,请求头,请求体,我们可以在相应位置携带值给服务器
图解:

但是 GET 或 HEAD 请求方式,浏览器会忽略请求体, 但不代表 GET/HEAD 方式无法发送请求体,使用 apifox 等接口调试工具是可以携带请求体的
非要说区别有如下几点
- 浏览器回退的时候,GET 不会重新提交,而 POST 会重新提交表单
- GET 会被浏览器主动缓存,POST 不会
- 再就是 url 上传查询参数和请求体传参的区别了 (实际上不是 GET 和 POST 区别了)
- url 上只能进行 url 编码,而请求体里支持多种编码格式
- url 上的参数会保留在浏览器历史记录里,而请求体不会被保留,除非用代码设置
原生 Ajax 的原理?
axios 库是对原生 Ajax 的 XMLHttpRequest 相关语法的封装
AJAX 原理是 XMLHttpRequest 相关语法
而原生 JS 代码参考 面试官:ajax 原理是什么?如何实现?
箭头函数和 function 函数区别?
箭头函数常用做回调函数使用,它无自己的 this, 无 arguments 对象,不能被 new 调用
一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么
- 浏览器查找域名对应的 IP 地址 (DNS 查询:
浏览器缓存->系统缓存->路由器缓存->ISPDNS 缓存->根域名服务器) - 浏览器向 Web 服务器发送一个 HTTP 请求(TCP 三次握手)
- (如果服务器设置了重定向)服务器 301 重定向(从
HTTP://example.com重定向到HTTP://www.example.com) - 浏览器跟踪重定向地址,请求另一个带 www 的网址
- 服务器处理请求(通过路由读取资源)
- 服务器返回一个 HTTP 响应(报头中把 Content-type 设置为 'text/html')
- 浏览器进 DOM 树构建
- 浏览器发送请求获取嵌在 HTML 中的资源(如图片、音频、视频、CSS、JS 等)
- 浏览器显示完成页面
- 浏览器发送异步请求
- 浏览器查找域名对应的 IP 地址 (DNS 查询:
DOM 事件流与事件委托
事件流
事件流:⼜称为事件传播,是⻚⾯中接收事件的顺序。DOM2 级事件规定的事件流包括了 3 个阶段:
- 事件捕获阶段(capture phase)
- 处于⽬标阶段(target phase)
- 事件冒泡阶段(bubbling phase)
事件捕获(Event Capturing)
- 事件开始由较为不具体的节点接收后,然后开始逐级向下传播到最具体的元素上。
- 事件捕获的最大作用在于:事件在到达预定⽬标之前就可以捕获到它。
- 如果仍以上面那段 HTML 代码为例,当点击按钮后,在事件捕获的过程中,document 对象会首先接收到这个
click事件,然后再沿着 DOM 树依次向下,直到<button>。具体顺序如下:
- document 对象
- html 元素
- body 元素
- button 元素
事件冒泡(Event Bubbling)
事件开始由最具体的元素(⽂档中嵌套层次最深的那个节点)接收到后,开始逐级向上传播到较为不具体的节点。
html<html> <head> <title>Document</title> </head> <body> <button>按钮</button> </body> </html>如果点击了上面页面代码中的
<button>按钮,那么该click点击事件会沿着 DOM 树向上逐级传播,在途经的每个节点上都会发生,具体顺序如下:- button 元素
- body 元素
- html 元素
- document 对象
事件委托
事件委托:利用了事件冒泡的机制,在较上层位置的元素上添加一个事件监听函数,来管理该元素及其所有子孙元素上的某一类的所有事件。
示例
html<ul id="list"> <li>111</li> <li>222</li> <li>333</li> <li>444</li> <li>555</li> </ul> <script type="text/javascript"> // ⽗元素 var list = document.getElementById('list'); // 为⽗元素绑定事件,委托管理它的所有⼦元素 li 的点击事件 list.onclick = function (event) { var currentTarget = event.target; if (currentTarget.tagName.toLowerCase() === 'li') { alert(currentTarget.innerText); } }; </script>适用场景:在绑定大量事件的时候,可以选择事件委托
优点
- 事件委托可以减少事件注册数量,节省内存占⽤!
- 当新增⼦元素时,⽆需再次做事件绑定,因此非常适合动态添加元素 (vue 解析模板时,会对新创建的元素,额外进行绑定的)